/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package colonia;
import beans.Mapa;
import java.util.*;
/**
 *
 * @author Fernando
 */
public class MatrizFeromona {
    
    private byte[][] _value;
    private float _evaporationRatio;
    private ArrayList<Nodo> _nodes;
    private static MatrizFeromona p=null;
    
    private MatrizFeromona(ArrayList<Nodo> nodes,float start){
        _nodes = nodes;
        _evaporationRatio = (float) 0.1;
        _value = new byte[nodes.size()][nodes.size()]; 
        
        for(int i=0;i<nodes.size();i++){
            for(int j=0;j<nodes.size();j++){
                _value[i][j]=(byte)(start*100);
            }
        }
        
    }
    
    public static MatrizFeromona getInstance(ArrayList<Nodo> nodes,float start){
        if(p==null){
            p= new MatrizFeromona(nodes,start);
        }
        return p;
    }
    
    
    public void updatePheromoneTrail(ArrayList<Nodo> route){
        for(int i=1;i < route.size();i++){
            float t0 = this.getLevel(route.get(i-1), route.get(i));
            float newValue = (1-_evaporationRatio)*t0 + _evaporationRatio * 1;
            this.setLevel(route.get(i-1), route.get(i), newValue);
        }
    }
    
    public void actualizarMejorRastroFeromona(ArrayList<Nodo> route, float bestCost){
        Nodo n1,n2;
        for(int i=1;i < route.size();i++){
            n1 = route.get(i-1);
            n2 = route.get(i);
            float t0 = this.getLevel(n1, n2);
            float newValue =(1-_evaporationRatio)*t0 + _evaporationRatio/bestCost * 1;
            this.setLevel(n1, n2, newValue);
        }
    }
    
    public float getLevel(Nodo node1, Nodo node2){
        int n1 = Mapa.getIndicePunto(node1.getX(), node1.getY());
        int n2 = Mapa.getIndicePunto(node2.getX(), node2.getY());
        return (float)(_value[n1][n2])/100;
    }
    
    public void setLevel(Nodo node1, Nodo node2,float level){
        int n1 = Mapa.getIndicePunto(node1.getX(), node1.getY());
        int n2 = Mapa.getIndicePunto(node2.getX(), node2.getY());
        _value[n1][n2] =(byte) (level *100);
    }
}
